import { uuid } from '@/utils/util';
import type { FileItem, SelectType, UploadFileProps } from './index';
import Taro from '@tarojs/taro';
// import * as DocumentPicker from 'expo-document-picker';

let uploadRequest: UploadFileProps['onUploadRequest'];

/** 设置默认的上传文件方法 */
export function setDefaultOnUploadRequest(fn: UploadFileProps['onUploadRequest']) {
  uploadRequest = fn;
}

export function getDefaultOnUploadRequest() {
  return uploadRequest;
}

export function transValueToSelectedValue(
  value: any,
  joinValues: boolean,
  delimiter: string,
  labelField: string,
  valueField: string,
  urlField: string,
) {
  let list: FileItem[] = [];
  if (!value) {
    return list;
  }
  if (joinValues) {
    if (typeof value !== 'string') {
      console.warn('uploadFile transValueToSelectedValue 数据解析异常 非string', arguments);
    } else {
      list = value.split(delimiter).map(item => {
        return {
          id: uuid(),
          [labelField]: extractFilename(item),
          [valueField]: item,
          [urlField || valueField]: item,
        };
      });
    }
  } else {
    if (!Array.isArray(value)) {
      console.warn('uploadFile transValueToSelectedValue 数据解析异常 非array', arguments);
    } else {
      list = value.map(item => {
        if (typeof item === 'string') {
          return {
            id: uuid(),
            [labelField]: extractFilename(item),
            [valueField]: item,
            [urlField || valueField]: item,
          };
        } else {
          return {
            id: uuid(),
            [labelField]: extractFilename(item[valueField]),
            [valueField]: item[valueField],
            [urlField || valueField]: item[urlField || valueField],
            ...item,
          };
        }
      });
    }
  }
  return list;
}

export function transSelectedValueToValue(
  selectedValue: FileItem[],
  joinValues: boolean,
  delimiter: string,
  valueField: string,
  extractValue: boolean,
) {
  let value: any;
  if (joinValues) {
    value = selectedValue.map(item => item[valueField]).join(delimiter);
  } else {
    if (extractValue) {
      value = selectedValue.map(item => item[valueField]);
    } else {
      value = selectedValue.concat();
    }
  }
  return value;
}

/** 解析文件名 把https://www.a.com/b.png?t=1 解析成 b.png */
export function extractFilename(url: string) {
  if (!url || typeof url !== 'string') return '';
  return url.split('/').pop()?.split('?').shift() || url;
}

/**
 * 获取文件后缀名
 * @param url
 * console.log(getFileExtension('blob://aaa')); // 输出 ''
 *
 * console.log(getFileExtension('http://w.com/b.jpg?t=1')); // 输出 'jpg'
 */
export function getFileExtension(url) {
  if (!url || typeof url !== 'string') return '';
  const filename = url.split('/').pop();
  if (!filename || filename.indexOf('.') === -1) return '';
  const path = url.split('?')[0];
  const extension = path.split('.').pop();
  return extension;
}

/** 校验文件名是否符合accept */
function checkFileTypeAccept(url: string, accept: string) {
  if (!accept || !url || typeof url !== 'string' || !getFileExtension(url)) {
    return true;
  }
  return accept.split(',').includes('.' + getFileExtension(url));
}

export function chooseFileByType({ selectType, accept }: { selectType: SelectType; accept?: string }): Promise<string | object> {
  return new Promise((resolve, reject) => {
    if (selectType === 'image') {
      Taro.chooseImage({
        count: 1,
        success: function (res) {
          // 返回选定照片的本地文件路径列表，tempFilePath可以作为img标签的src属性显示图片
          var tempFilePaths = res.tempFilePaths;
          console.log('chooseImage', tempFilePaths);
          if (res.tempFilePaths.length) {
            if (!checkFileTypeAccept(tempFilePaths[0], accept || '')) {
              return reject('文件后缀不符合要求');
            }
            resolve(tempFilePaths[0]);
          }
          resolve('');
        },
        fail() {
          resolve('');
        },
      });
    } else if (selectType === 'video') {
      Taro.chooseVideo({
        sourceType: ['album', 'camera'],
        success: res => {
          console.log('chooseVideo', res.tempFilePath);
          if (!checkFileTypeAccept(res.tempFilePath, accept || '')) {
            return reject('文件后缀不符合要求');
          }
          resolve(res.tempFilePath);
        },
        fail() {
          resolve('');
        },
      });
    } else if (selectType === 'file') {
      if (process.env.TARO_ENV === 'weapp') {
        Taro.chooseMessageFile({
          count: 1,
          type: 'file',
          success: res => {
            console.log('chooseMessageFile', res.tempFiles);
            const tempFilePaths = res.tempFiles;
            if (!checkFileTypeAccept(tempFilePaths[0].path, accept || '')) {
              return reject('文件后缀不符合要求');
            }
            resolve(tempFilePaths[0].path);
          },
          fail() {
            resolve('');
          },
        });
      } else if (process.env.TARO_ENV === 'h5') {
        function createFileInput(callback) {
          const input = document.createElement('input');
          input.type = 'file';
          input.multiple = false;
          if (accept) input.accept = accept;
          input.onchange = event => {
            const file = event.target.files[0];
            if (!checkFileTypeAccept(file.name, accept || '')) {
              input.remove();
              return reject('文件后缀不符合要求');
            }
            callback(URL.createObjectURL(file));
            input.remove();
          };
          input.click();
        }
        createFileInput(file => {
          console.log('选择的文件是：', file);
          resolve(file);
        });
      } else if (process.env.TARO_ENV === 'rn') {
        const DocumentPicker = require('expo-document-picker');
        DocumentPicker.getDocumentAsync({
          multiple: false,
          type: transAccept2MiniTypes(accept || '').length ? transAccept2MiniTypes(accept || '') : undefined,
        })
          .then(result => {
            if (!result.cancelled && result.assets?.length) {
              console.log('getDocumentAsync', result);
              // "assets": [{"mimeType": "image/png", "name": "Screenshot_20240318-150202.png", "size": 183443, "uri": "file:///data/user/0/com.taro73/cache/DocumentPicker/f1043133-e1a5-40e5-82b3-90a2b6de0ed6.png"}]
              resolve(result.assets[0].uri);
            } else {
              resolve('');
            }
          })
          .catch(err => {
            resolve('');
          });
      }
    } else {
      reject('不支持的选择类型');
    }
  });
}

export function chooseFileByTypes({
  selectTypes,
  selectTypeLabels,
  accept,
}: {
  selectTypes: SelectType[];
  selectTypeLabels?: { [key in SelectType]: string };
  accept?: string;
}): Promise<string | object> {
  const labels: { [key in SelectType]: string } = selectTypeLabels || getSelectTypeLabels();
  const itemList = selectTypes.map(type => labels[type]);
  return new Promise((resolve, reject) => {
    try {
      if (selectTypes.length > 1) {
        Taro.showActionSheet({
          itemList,
          success: res => {
            chooseFileByType({ selectType: selectTypes[res.tapIndex], accept }).then(resp => {
              resolve(resp);
            });
          },
          fail: res => {
            resolve('');
          },
        });
      } else {
        chooseFileByType({ selectType: selectTypes[0], accept }).then(resp => {
          resolve(resp);
        });
      }
    } catch (error) {
      reject(error);
    }
  });
}

/** 获取选择文件类型的描述 */
export function getSelectTypeLabels() {
  return {
    image: '图片',
    video: '视频',
    file: '文件',
  };
}

/** 把accept转成minitypes */
export function transAccept2MiniTypes(accept: string) {
  const list: string[] = [];
  if (!accept) {
    return list;
  }
  const mimeTypes: { [extension: string]: string } = {
    '.aac': 'audio/aac',
    '.abw': 'application/x-abiword',
    '.apng': 'image/apng',
    '.arc': 'application/x-freearc',
    '.avif': 'image/avif',
    '.avi': 'video/x-msvideo',
    '.azw': 'application/vnd.amazon.ebook',
    '.bin': 'application/octet-stream',
    '.bmp': 'image/bmp',
    '.bz': 'application/x-bzip',
    '.bz2': 'application/x-bzip2',
    '.cda': 'application/x-cdf',
    '.csh': 'application/x-csh',
    '.css': 'text/css',
    '.csv': 'text/csv',
    '.doc': 'application/msword',
    '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    '.eot': 'application/vnd.ms-fontobject',
    '.epub': 'application/epub+zip',
    '.gz': 'application/gzip',
    '.gif': 'image/gif',
    '.htm': 'text/html',
    '.html': 'text/html',
    '.ico': 'image/vnd.microsoft.icon',
    '.ics': 'text/calendar',
    '.jar': 'application/java-archive',
    '.jpeg': 'image/jpeg',
    '.jpg': 'image/jpeg',
    '.js': 'text/javascript',
    '.json': 'application/json',
    '.jsonld': 'application/ld+json',
    '.mid': 'audio/midi',
    '.midi': 'audio/midi',
    '.mjs': 'text/javascript',
    '.mp3': 'audio/mpeg',
    '.mp4': 'video/mp4',
    '.mpeg': 'video/mpeg',
    '.mpkg': 'application/vnd.apple.installer+xml',
    '.odp': 'application/vnd.oasis.opendocument.presentation',
    '.ods': 'application/vnd.oasis.opendocument.spreadsheet',
    '.odt': 'application/vnd.oasis.opendocument.text',
    '.oga': 'audio/ogg',
    '.ogv': 'video/ogg',
    '.ogx': 'application/ogg',
    '.opus': 'audio/opus',
    '.otf': 'font/otf',
    '.png': 'image/png',
    '.pdf': 'application/pdf',
    '.php': 'application/x-httpd-php',
    '.ppt': 'application/vnd.ms-powerpoint',
    '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    '.rar': 'application/vnd.rar',
    '.rtf': 'application/rtf',
    '.sh': 'application/x-sh',
    '.svg': 'image/svg+xml',
    '.tar': 'application/x-tar',
    '.tif': 'image/tiff',
    '.tiff': 'image/tiff',
    '.ts': 'video/mp2t',
    '.ttf': 'font/ttf',
    '.txt': 'text/plain',
    '.vsd': 'application/vnd.visio',
    '.wav': 'audio/wav',
    '.weba': 'audio/webm',
    '.webm': 'video/webm',
    '.webp': 'image/webp',
    '.woff': 'font/woff',
    '.woff2': 'font/woff2',
    '.xhtml': 'application/xhtml+xml',
    '.xls': 'application/vnd.ms-excel',
    '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    '.xml': 'application/xml',
    '.xul': 'application/vnd.mozilla.xul+xml',
    '.zip': 'application/zip',
    '.3gp': 'video/3gpp',
    '.3g2': 'video/3gpp2',
    '.7z': 'application/x-7z-compressed',
  };
  return accept
    .split(',')
    .map(v => mimeTypes[v])
    .filter(v => !!v);
}

/** 常见图片类型 */
export const imageAccepts = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'svg', 'tiff'];

/**
 * h5 file对象转换base64
 * @param file blob类型
 */
export function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    let fileResult = '';
    reader.readAsDataURL(file);
    reader.onload = () => {
      fileResult = reader.result;
    };
    reader.onerror = error => {
      reject(error);
    };
    reader.onloadend = () => {
      resolve(fileResult);
    };
  });
}
